#include "stdio.h"
#include "sc.h"
#include "timer.h"
#include "math.h"

#define TRIALS   100
#define OUTSTREAM stdout

typedef int STREAMPTR;

NeighbourhoodToPixelOp()
nbh3(in stream float i[-1..1][-1..1],
     out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-1][-1];
  acc += i[-1][ 0];
  acc += i[-1][ 1];
  acc += i[ 0][-1];
  acc += i[ 0][ 0];
  acc += i[ 0][ 1];
  acc += i[ 1][-1];
  acc += i[ 1][ 0];
  acc += i[ 1][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh5(in stream float i[-2..2][-2..2],
     out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-2][-1];
  acc += i[-1][ 0];
  acc += i[-1][ 1];
  acc += i[ 0][-1];
  acc += i[ 0][ 0];
  acc += i[ 0][ 1];
  acc += i[ 1][-1];
  acc += i[ 1][ 0];
  acc += i[ 2][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh7(in stream float i[-3..3][-3..3],
     out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-3][-1];
  acc += i[-2][ 0];
  acc += i[-1][ 1];
  acc += i[ 0][-1];
  acc += i[ 0][ 0];
  acc += i[ 0][ 1];
  acc += i[ 1][-1];
  acc += i[ 2][ 0];
  acc += i[ 3][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh9(in stream float i[-4..4][-4..4],
     out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-4][-1];
  acc += i[-3][ 0];
  acc += i[-2][ 1];
  acc += i[-1][-1];
  acc += i[ 0][ 0];
  acc += i[ 1][ 1];
  acc += i[ 2][-1];
  acc += i[ 3][ 0];
  acc += i[ 4][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh11(in stream float i[-5..5][-5..5],
     out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-5][-1];
  acc += i[-4][ 0];
  acc += i[-3][ 1];
  acc += i[-2][-1];
  acc += i[ 0][ 0];
  acc += i[ 2][ 1];
  acc += i[ 3][-1];
  acc += i[ 4][ 0];
  acc += i[ 5][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh13(in stream float i[-6..6][-6..6],
      out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-6][-1];
  acc += i[-5][ 0];
  acc += i[-4][ 1];
  acc += i[-3][-1];
  acc += i[ 0][ 0];
  acc += i[ 3][ 1];
  acc += i[ 4][-1];
  acc += i[ 5][ 0];
  acc += i[ 6][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh15(in stream float i[-7..7][-7..7],
      out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-7][-1];
  acc += i[-6][ 0];
  acc += i[-5][ 1];
  acc += i[-4][-1];
  acc += i[ 0][ 0];
  acc += i[ 4][ 1];
  acc += i[ 5][-1];
  acc += i[ 6][ 0];
  acc += i[ 7][ 1];

  *o = acc;
}

NeighbourhoodToPixelOp()
nbh17(in stream float i[-8..8][-8..8],
      out stream float *o)
{
  int ii, y, x;
  float acc = 0;

  acc += i[-8][-1];
  acc += i[-7][ 0];
  acc += i[-6][ 1];
  acc += i[-5][-1];
  acc += i[ 0][ 0];
  acc += i[ 5][ 1];
  acc += i[ 6][-1];
  acc += i[ 7][ 0];
  acc += i[ 8][ 1];

  *o = acc;
}

int MAIN(int argc, char **argv)
{
  int i, k;
  STREAMPTR a=1, b=2, c=3, d=4, image=5;
  tmr_t timer = tmrInit();

  scInit(argc, argv);
  _setbuffersize(4194304);

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh3(image, image);
    nbh3(image, image);
    nbh3(image, image);
    nbh3(image, image);
    nbh3(image, image);
    nbh3(image, image);
    nbh3(image, image);
    nbh3(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 1, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh5(image, image);
    nbh5(image, image);
    nbh5(image, image);
    nbh5(image, image);
    nbh5(image, image);
    nbh5(image, image);
    nbh5(image, image);
    nbh5(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 2, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh7(image, image);
    nbh7(image, image);
    nbh7(image, image);
    nbh7(image, image);
    nbh7(image, image);
    nbh7(image, image);
    nbh7(image, image);
    nbh7(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 3, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh9(image, image);
    nbh9(image, image);
    nbh9(image, image);
    nbh9(image, image);
    nbh9(image, image);
    nbh9(image, image);
    nbh9(image, image);
    nbh9(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 4, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh11(image, image);
    nbh11(image, image);
    nbh11(image, image);
    nbh11(image, image);
    nbh11(image, image);
    nbh11(image, image);
    nbh11(image, image);
    nbh11(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 5, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh13(image, image);
    nbh13(image, image);
    nbh13(image, image);
    nbh13(image, image);
    nbh13(image, image);
    nbh13(image, image);
    nbh13(image, image);
    nbh13(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 6, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh15(image, image);
    nbh15(image, image);
    nbh15(image, image);
    nbh15(image, image);
    nbh15(image, image);
    nbh15(image, image);
    nbh15(image, image);
    nbh15(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 7, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  for (i=0; i < TRIALS; i++)
  {
    tmrStart(&timer);

    generate(scint(4096), image);

    nbh17(image, image);
    nbh17(image, image);
    nbh17(image, image);
    nbh17(image, image);
    nbh17(image, image);
    nbh17(image, image);
    nbh17(image, image);
    nbh17(image, image);
    
    discard(image);

    _schedule(0);
    _awaitall();

    tmrStop(&timer);

    fprintf(OUTSTREAM, "T(%d, %d) = %f;\n", 8, i+1, tmrGetValueInUs(&timer)/1000.0);
  }

  return scExit();
}
